package hotel.quartz.oversea.job.meituan;
import hotel.base.oversea.constant.CommonConstants;
import hotel.base.oversea.constant.MeituanConstants;
import hotel.base.oversea.constant.enums.MessageEnums;
import hotel.base.oversea.utils.DateUtil;
import hotel.base.oversea.utils.GsonUtils;
import hotel.base.oversea.utils.SendUtils;
import hotel.base.oversea.utils.StringUtil;
import hotel.base.oversea.vo.meituan.MtHotelRoomDeatilVo;
import hotel.base.oversea.vo.meituan.MtHotelRoomDownVo;
import hotel.quartz.oversea.config.service.RedisService;
import hotel.quartz.oversea.job.base.BaseJob;
import hotel.quartz.oversea.vo.meituan.MtHotelRealRoomVo;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobExecutionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.ObjectUtils;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 静态物理房型：校验房型信息
 *               校验窗户信息
 *
 * @description: Basic Mt Rooms Info Check Update Job
 * @author: qiuyy
 * @date: 2020-05-26 13:22
 * @version: V1.0
 */
@Slf4j
public class BasicMtRoomsInfoCheckUpdateJob implements BaseJob {
    private String timestamp = "Bmgicuj"+String.valueOf(System.currentTimeMillis())+ StringUtil.getFourRandom();
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private RedisService redisService;

    private void setTimestamp(String timestamp){
        this.timestamp = timestamp;
    }

    @Override
    @SneakyThrows
    public void execute(JobExecutionContext jobExecutionContext) {
        log.info("Basic Mt Rooms Info Check Update Job {} >>>>>>>> 房型信息校验定时器 执行时间: {}", timestamp, DateUtil.getCurrTime());
        Long size = redisService.queueSize(CommonConstants.SWITCH_MT_HOTELS_LAST_REQ_ROOMS);
        log.info("Basic Mt Rooms Info Check Update Job {} >>>>>>>> 房型信息校验定时器 最新更新房型酒店size={}", timestamp,size);
        if(size>0){
            Map<String,Map<String,String>> changeHotelsWindowFailMap = new HashMap<>();//变化窗户即认为失效
            for (int i = 0; i < size; i++) {
                String hotelId = (String)redisService.RPop(CommonConstants.SWITCH_MT_HOTELS_LAST_REQ_ROOMS);
                if(!ObjectUtils.isEmpty(hotelId)){
                    log.info("Basic Mt Rooms Info Check Update Job {} >>>>>>>> 房型信息校验定时器 进入hotelId={},i={},", timestamp,i,hotelId);
                    String thisHotelRoomsInfoStr = (String)redisService.get(CommonConstants.SWITCH_MT_ONE_HOTEL_ROOMS_REDIS+hotelId);
                    if(!ObjectUtils.isEmpty(thisHotelRoomsInfoStr)){
                        log.info("Basic Mt Rooms Info Check Update Job {} >>>>>>>> 房型信息校验定时器 存在房型信息hotelId={}, i={},thisHotelRoomsInfo={}", timestamp,hotelId,i,thisHotelRoomsInfoStr);
                        List<MtHotelRealRoomVo> apiRoomList = GsonUtils.jsonToList(thisHotelRoomsInfoStr,MtHotelRealRoomVo.class);
                        if(!ObjectUtils.isEmpty(apiRoomList)){
                            //携程上架的房型集合
                            Object redisOneHotelRoomList = redisService.hmGet(CommonConstants.SWITCH_SALE_HOTEL_ROOM_LIST,Integer.valueOf(hotelId));
                            log.info("Basic Mt Rooms Info Check Update Job  该酒店得到上架房型信息hotelId={}， i={}，redisOneHotelRoomList={}",hotelId,i, GsonUtils.GsonString(redisOneHotelRoomList));
                            if(!ObjectUtils.isEmpty(redisOneHotelRoomList)) {
                                List<Integer> oneHotelSwUpRoomIdList = (List<Integer>) redisOneHotelRoomList;//该酒店携程上架的房型集合
                                if(!ObjectUtils.isEmpty(oneHotelSwUpRoomIdList)){//遍历接口最新缓存的美团该酒店房型集合
                                    for (MtHotelRealRoomVo oneApiRoomInfo : apiRoomList) {
                                        Integer realRoomId = oneApiRoomInfo.getRealRoomBaseInfo().getRealRoomId();
                                        if(oneHotelSwUpRoomIdList.contains(realRoomId)){
                                            //接口物理房型为携程上架房型时，校验窗户信息
                                            Integer hasWindows = null;
                                            hasWindows = (Integer)redisService.hmGet(CommonConstants.SWITCH_CREATE_ROOM_WINDOW_TYPE,hotelId+"_"+realRoomId);
                                            if(!ObjectUtils.isEmpty(hasWindows)){
                                                log.info("BasicMtRoomsInfoCheckUpdateJob 进入第二版 窗户规则：hasWindows={}",hasWindows);
                                            }else{
                                                hasWindows = (Integer) redisService.get(CommonConstants.SWITCH_CREATE_ROOM_WINDOW_TYPE+hotelId+"_"+realRoomId);
                                                log.info("BasicMtRoomsInfoCheckUpdateJob 进入第一版 窗户规则：hasWindows={}",hasWindows);
                                            }

                                            Integer apiWindow = oneApiRoomInfo.getRealRoomBaseInfo().getWindow();
                                            log.info("Basic Mt Rooms Info Check Update Job 接口房型id比对到携程上架房型hotelId={}，realRoomId={},hasWindows={},apiWindow={}",hotelId,realRoomId,hasWindows,apiWindow);
                                            if(!ObjectUtils.isEmpty(hasWindows)){
                                                if(!ObjectUtils.isEmpty(apiWindow)){
                                                    if(BigDecimal.valueOf(hasWindows).compareTo(BigDecimal.valueOf(apiWindow))!=0){
                                                        log.info("Basic Mt Rooms Info Check Update Job 存在房型窗户变化 hotelId={},realRoomId={}，hasWindows={}，apiWindow={}",hotelId,realRoomId,hasWindows,apiWindow);
                                                        Map<String,String> thisOnechangeWindowFailMap = null;
                                                        if(!ObjectUtils.isEmpty(changeHotelsWindowFailMap.get(hotelId))){
                                                            thisOnechangeWindowFailMap = changeHotelsWindowFailMap.get(hotelId);
                                                        }else{
                                                            thisOnechangeWindowFailMap = new HashMap<>();
                                                        }
                                                        thisOnechangeWindowFailMap.put(String.valueOf(realRoomId),apiWindow+"_"+hasWindows);
                                                        changeHotelsWindowFailMap.put(hotelId,thisOnechangeWindowFailMap);
                                                    }
                                                }else{
                                                    log.info("Basic Mt Rooms Info Check Update Job 异常，美团接口返回房型没有窗户信息hotelId={},realRoomId={}",hotelId,realRoomId);
                                                    //推送钉钉
                                                    SendUtils.dingMsgNotLog("[BASIC-CHECK-ROOM-ERROR]美团房型异常，美团接口返回没有窗户信息 ", DateUtil.getCurrTime()+" 酒店id="+hotelId+" 房型id="+realRoomId, MessageEnums.genre.GOODS_STATUS_AND_PRICE.getCode(),restTemplate);

                                                }
                                            }else{
                                                log.info("Basic Mt Rooms Info Check Update Job 异常，携程上架房型没有窗户缓存信息hotelId={},realRoomId={}",hotelId,realRoomId);
                                                //推送钉钉
                                                SendUtils.dingMsgNotLog("[BASIC-CHECK-ROOM-ERROR]房型校验异常，携程上架房型没有窗户缓存信息 ", DateUtil.getCurrTime()+" 酒店id="+hotelId+" 房型id="+realRoomId, MessageEnums.genre.GOODS_STATUS_AND_PRICE.getCode(),restTemplate);
                                            }
                                        }
                                    }
                                }
                            }else{
                                log.info("Basic Mt Rooms Info Check Update Job {} >>>>>>>> 房型信息校验定时器 该酒店携程上架房型无数据 i={},hotelId={}", timestamp,i,hotelId);
                            }
                        }else{
                            log.info("Basic Mt Rooms Info Check Update Job {} >>>>>>>> 房型信息校验定时器 该酒店jsonToList异常无房型信息 i={},hotelId={},thisHotelRoomsInfo={}", timestamp,i,hotelId,thisHotelRoomsInfoStr);
                        }

                    }else{
                        log.info("Basic Mt Rooms Info Check Update Job {} >>>>>>>> 房型信息校验定时器 异常该酒店在携程无房型信息 i={},hotelId={},thisHotelRoomsInfo={}", timestamp,i,hotelId,thisHotelRoomsInfoStr);
                    }
                }else{
                    log.info("Basic Mt Rooms Info Check Update Job {} >>>>>>>> 房型信息校验定时器 已无可执行数据队列为空: i={}", timestamp,i);
                }

            }
            log.info("Basic Mt Rooms Info Check Update Job {} 多酒店 changeHotelsWindowFailMap={}", GsonUtils.GsonString(changeHotelsWindowFailMap));
            if(!ObjectUtils.isEmpty(changeHotelsWindowFailMap)){
                log.info("Basic Mt Rooms Info Check Update Job {} changeHotelsWindowFailMap长度={}",changeHotelsWindowFailMap.size());
                for (Map.Entry oneHotel:changeHotelsWindowFailMap.entrySet()){
                    String hotelId = (String)oneHotel.getKey();
                    Map<String,String> thisHotelRoomInfoListCheck = (Map<String,String>)oneHotel.getValue();
                    if(!ObjectUtils.isEmpty(thisHotelRoomInfoListCheck)){
                        List<MtHotelRoomDeatilVo> mtRoomListPushSw = new ArrayList<>();
                        for (Map.Entry oneRoom:thisHotelRoomInfoListCheck.entrySet()){
                            MtHotelRoomDeatilVo mtHotelRoomDeatilVo = new MtHotelRoomDeatilVo();
                            mtHotelRoomDeatilVo.setMtRoomId(Integer.valueOf((String)oneRoom.getKey()));
                            mtHotelRoomDeatilVo.setGenre(0);
                            mtRoomListPushSw.add(mtHotelRoomDeatilVo);
                        }
                        MtHotelRoomDownVo mtHotelRoomDownVo = new MtHotelRoomDownVo();
                        mtHotelRoomDownVo.setMtHotelId(Integer.valueOf(hotelId));
                        mtHotelRoomDownVo.setMtRoomList(mtRoomListPushSw);
                        log.info("Basic Mt Rooms Info Check Update Job 构建失效房型数据加入队列等待处理 hotelId={},mtHotelRoomDownVo：{}",hotelId, GsonUtils.GsonString(mtHotelRoomDownVo));
                        log.info("构建失效房型数据加入队列等待处理 hotelId={},mtHotelRoomDownVo：{}，queuesize={}",hotelId, GsonUtils.GsonString(mtHotelRoomDownVo),redisService.queueSize(MeituanConstants.REDIS_QUEUE_BASIC_REAL_ROOM_UPDATE_TO_SWITCHS));
                        SendUtils.dingMsgNotLog("[BASIC-CHECK-ROOM]校验携程上架房型窗户信息,存在变化失效", DateUtil.getCurrTime()+" 等待半小时定时器处理："+ GsonUtils.GsonString(mtHotelRoomDownVo)+" 窗户数据："+ GsonUtils.GsonString(changeHotelsWindowFailMap)+" 当前变化房型待处理队列="+redisService.queueSize(MeituanConstants.REDIS_QUEUE_BASIC_REAL_ROOM_UPDATE_TO_SWITCHS), MessageEnums.genre.GOODS_STATUS_AND_PRICE.getCode(),restTemplate);
                    }else{
                        log.info("Basic Mt Rooms Info Check Update Job 异常转换 hotelId={},thisHotelRoomInfoListCheck={}",hotelId, GsonUtils.GsonString(thisHotelRoomInfoListCheck));
                    }
                }
            }
        }

        log.info("Basic Mt Rooms Info Check Update Job {} >>>>>>>> 房型信息校验定时器 结束时间: {},{}",timestamp, DateUtil.getCurrTime());

    }


}
